<script setup lang="ts">
// 主要用能设备
import ContextmenuBox from './ContextmenuBox.vue'
import { uuid } from '@/utils'

const props = defineProps<{
  gradeType: number
  gradeTypeText: string
  data: [string, ...(string | number)[]][]
  readonly?: boolean
  showSummary?: boolean
}>()
const lists = ref<
  {
    uuid: string
    data: (string | number)[]
  }[]
      >([])
const summary = computed(() => {
  const listsValue = toValue(lists)
  // except `gradeName`
  const needAccumulateValue = listsValue.map(({ data }) =>
    data.slice(1),
  )
  return {
    uuid: uuid('temp_'),
    data: [
      '合计',
      ...needAccumulateValue.reduce((acc, vv) => {
        vv.forEach((v, i) => {
          acc[i] = (Number(acc[i]) || 0) + (Number(v) || 0)
        })
        return acc
      }, []),
    ],
  }
})
const rowIndex0Rowspan = computed(() => {
  const count = lists.value.length
  return props.showSummary ? count + 1 : count
})

watchEffect(() => {
  lists.value = props.data
    .map(([id, ...rest]) => ({
      uuid: id,
      data: rest,
    }))
})

const left = ref(0)
const top = ref(0)
const rowIndex = ref(-1)
const visible = ref(false)

function setVisible(v: boolean) {
  visible.value = v
}

function onContextmenu(evt: MouseEvent, index: number) {
  evt.preventDefault()
  const { clientX, clientY } = evt

  left.value = clientX
  top.value = clientY

  setVisible(true)
  rowIndex.value = index
}

function delRow() {
  const index = toValue(rowIndex)
  setVisible(false)
  ElMessageBox.confirm('确定要删除这一行？', '温馨提示')
    .then(() => {
      lists.value.splice(index, 1)
    })
    .catch(() => {})
}

function createAEmptyRow() {
  return {
    uuid: uuid('temp_'),
    data: Array(15).fill(''),
  }
}

function appendRow() {
  const index = toValue(rowIndex)
  const emptyRow = createAEmptyRow()
  if (index > -1) {
    lists.value.splice(index + 1, 0, emptyRow)
  }
  setVisible(false)
}

function prependRow() {
  const index = toValue(rowIndex)
  const emptyRow = createAEmptyRow()
  if (index > -1) {
    lists.value.splice(index, 0, emptyRow)
  }
  setVisible(false)
}

defineExpose({
  lists,
})
</script>

<template>
  <tr v-for="(item, row) in lists" :key="item.uuid">
    <td v-if="row === 0" :rowspan="rowIndex0Rowspan">
      <div class="span-cell">
        {{ gradeTypeText }}
      </div>
    </td>
    <td
      v-for="(_d, col) in item.data"
      :key="`${item.uuid}_${col}`"
    >
      <div v-if="readonly" class="span-cell">
        {{ item.data[col] }}
      </div>
      <div v-else class="input-cell">
        <input
          v-model="item.data[col]"
          type="text"
          @contextmenu="evt => onContextmenu(evt, row)"
        >
      </div>
    </td>
  </tr>
  <tr v-if="showSummary">
    <td
      v-for="(_s, col) in summary.data"
      :key="col"
      class="is-calculable"
    >
      <div class="span-cell">
        {{ summary.data[col] }}
      </div>
    </td>
  </tr>
  <ContextmenuBox
    v-model="visible"
    :left="left"
    :top="top"
    @del-row="delRow"
    @append-row="appendRow"
    @prepend-row="prependRow"
  />
</template>
